【9.14補充內容】增加了fetch API的應用,然後修改了一些async & await的範例。
async & await是一個基於promise的語法糖。
運作原理和promise一模一樣,主要包含兩個部分:
async
: async function 宣告一個非同步函式,可以告訴function在最後回傳一個promise。await
: await必須放在任何基於promise的函數之前,等到獲得resolve的資料後,再執行後續動作。假設原來的程式碼長這樣:
function greeting() {
return new Promise( (resolve,reject) => {
resolve("Hello");
});
}
greeting()
.then((value) => console.log(value));
// output: "Hello"
我們先嘗試使用async
:
async function greeting() { return "Hello" };
greeting()
.then((value) => console.log(value));
// output: "Hello"
因為非同步函式greeting()
回傳的會是一個promise,所以可以省略建構promisenew Promise
。
而await必須放在任何基於promise的函數之前,
改寫new Promise
建構式的寫法:
async function greeting(){
let example = await new Promise( (resolve,reject) => {
resolve("Hello");
});
return example;
}
greeting()
.then((value) => console.log(value));
// output: "Hello"
await的作用是,
在得到resolve的物件後,才執行let example
的給值。。
更簡便的寫法,可以使用Promise.resolve()
函式:
async function greeting(){
let example = await Promise.resolve("Hello");
return example;
}
greeting()
.then((value) => console.log(value));
// output: "Hello"
我們可以用Promise.resolve()
這個方法回傳一個 指定resolve值的promise,
這裡的重點是 一樣要加上await。
async function greeting(){
let example = await Promise.reject("Error");
return example;
}
greeting()
.then((value) => console.log(value))
.catch((error) => console.log(error))
// output: "Error"
我們可以用Promise.reject()
這個方法,則回傳一個reject的promise,
一樣可以用catch
來獲得錯誤訊息。
async & await 也可以搭配另一種處理錯誤訊息的方法,也就是 try
& catch
,
繼續改寫上面的例子:
async function greeting(){
try {
let example = await Promise.resolve("Hello");
console.log(example);
} catch (error) {
console.log(error);
}
}
greeting();
// output: "Hello"
try
負責正常獲得資料的處理,catch
則能直接獲取錯誤訊息。
好了!學到這裡可以嘗試接外部的API的,
但今天不用XHR(XMLHttpRequest),改用另一種更現代的方式。
API(Application Programming Interface)可以視為一種的工具,用於讓開發者便於請求資料。
Fetch API 提供了 fetch()
方法,fetch()
會回傳一個不論請求成功或失敗,都是 resolve 的 promise。
fetch()
的參數必須為請求資料的網址。
首先可以嘗試使用 Fetch 發送請求 ( request ),這裡我們使用 {JSON} Placeholder 作為例子。
( 可以參考 JSONPlaceholder - Free Fake REST API)
const request = 'https://jsonplaceholder.typicode.com/todos/1';
// fetch 會依照 request 去取得資料
fetch(request)
.then(response => response.json()) // json()會解析回傳的Response物件
.then(json => console.log(json))
執行步驟
fetch()
: 會依照參數裡指定的url去取得資料,且會直接resolve回傳的Promise,這個Promise 會包含 Response物件。.json()
: fetch()回傳的Promise( Body text )還要需要經過解析,.json()
是其中一種。.json()
會把fetch回來的Promise解析成JSON型別Promise。The
fetch()
method...
It returns a Promise that resolves to the Response to that request — as soon as the server responds with headers — even if the server response is an HTTP error status.
這樣會回傳URL裡todos/裡的第一筆資料。
// output:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
那來嘗試把資料改寫成async await吧!
原本的程式碼:
let requestURL = 'https://jsonplaceholder.typicode.com/todos/1';
fetch(requestURL)
.then((response) => {
return response.json();
})
.then((data) => {
console.log(`Title: ${data.title}`);
if (data.completed !== true){
console.log("Undo");
} else {
console.log("Done!!");
}
})
.catch((error) => {
console.log(`Error: ${error}`);
})
/* output:
"Title: delectus aut autem"
"Undo"
*/
改寫: 使用 async&await,並利用 try&catch 處理錯誤訊息。
let requestURL = 'https://jsonplaceholder.typicode.com/todos/1';
async function getTodoList(url){
try {
let response = await fetch(url);
let data = await response.json();
console.log(`Title: ${data.title}`);
if (data.completed !== true){
console.log("Undo");
} else {
console.log("Done!!");
}
} catch(error) {
cconsole.log(`Error: ${error}`);
}
}
getTodoList(requestURL);
fetch相較於XHR更強大且更有彈性(意思應該是fetch有很多功能),MDN提供了很多使用方式和範例,可以參考這個頁面: Using Fetch - Web APIs | MDN
一樣放上一些相關的問題:
【如內文有誤還請不吝指教>< 謝謝閱覽至此的各位:D】
參考資料: